package com.sharp.demo.socket;

import com.corundumstudio.socketio.AuthorizationListener;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIONamespace;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.sharp.authorization.service.token.TokenService;
import com.sharp.kernel.utils.ReflectionUtil;
import com.sharp.socket.io.bo.ChatMessage;
import com.sharp.socket.io.config.BaseLiveSocketIoConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.lang.reflect.Method;

import static com.sharp.socket.io.constant.ChatMessageConstant.*;

/**
 * Title: SocketIoConfig
 * Description: Copyright: Copyright (c) 2019 Company: BHFAE
 *
 * @author Sharp
 * @date 2020/9/22 15:42
 */
@Slf4j
@Configuration
public class DemoSocketIoConfig extends BaseLiveSocketIoConfig {

    @Value("${my.live.server.port}")
    private Integer port;
    @Resource
    private TokenService tokenService;

    @Override
    protected int port() {
        return port;
    }

    @Override
    protected AuthorizationListener onAuthorize() {
        return data -> {
            String token = data.getSingleUrlParam(TOKEN);
            String operator = data.getSingleUrlParam(OPERATOR);
            String roomId = data.getSingleUrlParam(ROOM_ID);
            log.info("token:{}, operator:{}, roomId:{}", token, operator, roomId);
            try {
                tokenService.verifyToken(token, operator);
            } catch (Exception e) {
                log.info("token 验证不通过");
                return false;
            }
            return true;
        };
    }

    @Override
    protected ConnectListener onConnect() {
        return client -> {
            super.baseOnConnect(client);
        };
    }

    @Override
    protected DisconnectListener onDisconnected() {
        return client -> {
            Object delegate = applicationContextInstance.getBean(DemoSocketIoEndpoint.class);
            Method method = ReflectionUtil.getMethod(DemoSocketIoEndpoint.class, "onDisconnect", SocketIOClient.class);
            ReflectionUtil.invoke(delegate, method, client);
        };
    }

    @Override
    protected void addEventDataListener(SocketIOServer socketIOServer, SocketIONamespace socketIONamespace) {
        socketIONamespace.addEventListener(CMD, ChatMessage.class, onEvent(socketIONamespace));
    }

    private DataListener<ChatMessage> onEvent(SocketIONamespace namespace) {
        return (client, message, ackSender) -> {
            log.debug("From: 客户端[{}-{}] - 收到消息 '{}'", namespace.getName(), client.getSessionId().toString(), message);
            switch (message.getMsgType()) {
                case CMD_LIVE_CONNECT_SUCCESS:
                case CMD_LIVE_JOIN_ROOM:
                    client.joinRoom(message.getContent());
                    break;
                case CMD_LIVE_LEAVE_ROOM:
                    client.leaveRoom(message.getContent());
                    break;
                default:
                    log.debug("未知消息类型 {}", message.getMsgType());
            }
        };
    }
}
